package com.tm.filter;

import com.alibaba.fastjson.JSONObject;
import com.tm.constants.RedisConstans;
import com.tm.enums.StatusCodeEnum;
import com.tm.utils.JwtUtils;
import com.tm.vo.Result;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.StringUtils;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author huangp
 * @create 2023-04-16 16:36
 */
@WebFilter(urlPatterns = "/api/*",filterName = "apiFilter")
public class ApiFilter implements Filter {

    public static ThreadLocal<Long> THREADLOCAL=  new ThreadLocal<>();

    private static String[] urls = {

            "/employee/login",
            "/employee/logout",
            "/backend/**",
            "/front/**",
            "/img/**",
            "/swagger-ui/**",
            "doc.html",
            "/webjars/**",
            "/api/sendMsg",
            "/api/user/login",

    };

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        //判断这个路径是否需要去拦截
        String requestURI = request.getRequestURI();
        Boolean checkUrl = checkUrl(requestURI);
        if (checkUrl) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }
        //得到授权的token请求头信息
        String authorization = request.getHeader("Authorization");
        //如果authorization为空就提示登陆失败
        if(StringUtils.isEmpty(authorization)){
            Result R = Result.error(StatusCodeEnum.NOT_LOGIN);
            //返回字符集编码
            response.setCharacterEncoding("UTF-8");
            response.getWriter().write(JSONObject.toJSONString(R));
            filterChain.doFilter(servletRequest,servletResponse);
        }
        //截取到整个token
        String[] split = authorization.split(" ");
        //拿到数组下表为1的token body信息
        String token = split[1];
        //解析token 获取redis中的key 查看redis中是否存在这个token
        Claims claims = jwtUtils.parseToken(token);
        String phone = (String) claims.get("phone");
        //调用常量类 生成tokenkey
        String tokenkey = RedisConstans.getKey(phone);
        //取出redis的token
        String redisToken = (String) redisTemplate.opsForValue().get(tokenkey);
        //如果RedisToken不为空 就给它设置过期时间
        if(StringUtils.isEmpty(redisToken)){
            //刷新token的过期时间
            redisTemplate.expire(tokenkey,RedisConstans.TOKEN_RXPIRE,RedisConstans.TIME_UNIT);
        }else{
            Result R = Result.error(StatusCodeEnum.NOT_LOGIN);
            //返回字符集编码
            response.setCharacterEncoding("UTF-8");
            response.getWriter().write(JSONObject.toJSONString(R));
            filterChain.doFilter(servletRequest,servletResponse);
        }

        filterChain.doFilter(servletRequest, servletResponse);

    }


    private static AntPathMatcher antPathMatcher = new AntPathMatcher();

    /**
     * 校验请求路径是否需要拦截
     * @param requestURI
     * @return
     */
    private static Boolean checkUrl(String requestURI) {
        for (String url : urls) {
            boolean match = antPathMatcher.match(url, requestURI);
            if (match) {
                return Boolean.TRUE;
            }
        }
        return Boolean.FALSE;
    }

}
